using System;
using System.Diagnostics;

namespace DotNet.DevOps.Tasks.Service.Helpers
{
    internal class Command
    {
        private readonly string _executable;
        private readonly string _arguments;
        private readonly int _timeout;

        public Command(string executable, string arguments, int timeout)
        {
            _executable = executable;
            _arguments = arguments;
            _timeout = timeout;
        }

        public string Run()
        {
            var commandProcess = CreateProcess();

            RunProcess(commandProcess);

            CheckProcessHasCompleted(commandProcess);

            return string.Format("{0} {1}", commandProcess.StandardOutput.ReadToEnd(), commandProcess.StandardError.ReadToEnd());
        }

        private Process CreateProcess()
        {
            return new Process
            {   
                EnableRaisingEvents = false,
                StartInfo = new ProcessStartInfo
                {
                    CreateNoWindow = true,
                    UseShellExecute = false,
                    RedirectStandardOutput = true,
                    RedirectStandardError = true,
                    WorkingDirectory = Environment.CurrentDirectory,
                    FileName = _executable,
                    Arguments = _arguments,
                }
            };
        }

        private void RunProcess(Process process)
        {
            process.Start();

            if (_timeout >= 0)
            {
                process.WaitForExit(_timeout);
            }
            else
            {
                process.WaitForExit();
            }
        }

        private void CheckProcessHasCompleted(Process process)
        {
            if (process.HasExited == false)
            {
                process.Kill();
                throw new Exception(string.Format("Timeout has occoured waiting for command to complete \"{0}\". Consider changing the timeout value for the task.", _arguments));
            }
        }

    }
}